#include "win32_file.h"

namespace renderit
{
	namespace fileio
	{
		win32_file::win32_file(const std::string& filename, int flag, HANDLE hfile)
		{
			name_ = filename;
			flag_ = flag;
			hfile_ = hfile;
		}

		void win32_file::close()
		{
			if (hfile_ != INVALID_HANDLE_VALUE)
			{
				::CloseHandle(hfile_);
			}
			delete this;
		}

		long long win32_file::size()
		{
			DWORD high_word = 0;
			DWORD low_word = ::GetFileSize(hfile_, &high_word);
			return (long long)((high_word << 32 & 0xFFFFFFFF00000000) | (low_word & 0xFFFFFFFF));
		}

		int win32_file::read(char * buf, int size)
		{
			DWORD bytes_read;
			BOOL b = ::ReadFile(
				hfile_,				// hFile
				buf,					// lpBuffer
				size,					// nNumberOfBytesToRead
				&bytes_read,	// lpNumberOfBytesRead
				NULL				// lpOverlapped
			);
			if (b) {
				return bytes_read;
			}
			DWORD err = GetLastError();
			return 0;
		}

		bool win32_file::write(const char * buf, int size)
		{
			DWORD number_written = 0;
			bool b = WriteFile(
				hfile_,
				buf,
				size,
				&number_written,
				NULL
			);
			return b;
		}

		bool win32_file::seek(long long offset, ESeekSet where)
		{
			DWORD low_word = (DWORD)(offset & 0xFFFFFFFF);
			LONG high_word = (DWORD)(offset >> 32);
			::SetFilePointer(hfile_, low_word, &high_word, where);
			return true;
		}

		long long win32_file::cur_pos()
		{
			DWORD low_word = 0;
			LONG high_word = 0;
			low_word = ::SetFilePointer(hfile_, low_word, &high_word, ESeek_Current);
			return (long long)((high_word << 32 & 0xFFFFFFFF00000000) | (low_word & 0xFFFFFFFF));
		}
	}
}